package org.codehaus.activemq.util;

import java.util.LinkedList;

public class BitArrayBin
{
  private LinkedList list;
  private int maxNumberOfArrays;
  private int currentIndex;
  private int firstIndex = -1;
  private int firstBin = -1;
  private int windowSize;

  public BitArrayBin(int windowSize)
  {
    this.windowSize = windowSize;
    this.maxNumberOfArrays = ((windowSize + 1) / 64 + 1);
    this.maxNumberOfArrays = Math.max(this.maxNumberOfArrays, 1);
    this.list = new LinkedList();
    for (int i = 0; i < this.maxNumberOfArrays; i++)
      this.list.add(new BitArray());
  }

  public boolean setBit(long index, boolean value)
  {
    boolean answer = true;
    BitArray ba = getBitArray(index);
    if (ba != null) {
      int offset = getOffset(index);
      if (offset >= 0) {
        answer = ba.set(offset, value);
      }
    }
    return answer;
  }

  public boolean getBit(long index)
  {
    boolean answer = index >= this.firstIndex;
    BitArray ba = getBitArray(index);
    if (ba != null) {
      int offset = getOffset(index);
      if (offset >= 0) {
        answer = ba.get(offset);
        return answer;
      }
    }
    else
    {
      answer = true;
    }
    return answer;
  }

  private BitArray getBitArray(long index)
  {
    int bin = getBin(index);
    BitArray answer = null;
    if (bin >= 0) {
      if (this.firstIndex < 0) {
        this.firstIndex = 0;
      }
      if (bin >= this.list.size()) {
        this.list.removeFirst();
        this.firstIndex += 64;
        this.list.add(new BitArray());
        bin = this.list.size() - 1;
      }
      answer = (BitArray)this.list.get(bin);
    }
    return answer;
  }

  private int getBin(long index)
  {
    int answer = 0;
    if (this.firstBin < 0) {
      this.firstBin = 0;
    }
    else if (this.firstIndex >= 0) {
      answer = (int)((index - this.firstIndex) / 64L);
    }
    return answer;
  }

  private int getOffset(long index)
  {
    int answer = 0;
    if (this.firstIndex >= 0)
    {
      answer = (int)(index - this.firstIndex - 64 * getBin(index));
    }
    return answer;
  }
}